package com.qingmeng.project.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qingmeng.apicommon.exception.BusinessException;
import com.qingmeng.apicommon.model.entity.InterfaceInfo;
import com.qingmeng.project.mapper.UserInterfaceInfoMapper;
import com.qingmeng.project.model.entity.InterfaceInfoCount;
import com.qingmeng.project.model.vo.InterfaceInfoVo;
import com.qingmeng.project.service.CountInterfaceService;
import com.qingmeng.project.service.InterfaceInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.qingmeng.apicommon.constant.RedisConstant.INTERFACE_INFO_COUNT_KEY;

@Service
@Slf4j
public class CountInterfaceInfoServiceImpl implements CountInterfaceService {
    @Resource
    private UserInterfaceInfoMapper userInterfaceInfoMapper;

    @Resource
    private InterfaceInfoService InterfaceInfoService;

    @Resource
    private RedisTemplate<String, List<InterfaceInfoVo>> redisTemplate;

    // 过期时间1小时
    public static final long INTERFACE_INFO_COUNT_EXPIRE = 1000 * 60 * 60; //常量过期时间


    /**
     * 接口调用统计
     * @return
     */
    @Override
    public List<InterfaceInfoVo> countInterface(Integer limit) {

        // 从缓存redis中获取数据
        if (redisTemplate.hasKey(INTERFACE_INFO_COUNT_KEY + limit)){
            log.info("从缓存中获取数据");
            return redisTemplate.opsForValue().get(INTERFACE_INFO_COUNT_KEY + limit);
        }
        //从数据库中查询
        log.info("从数据库中获取数据");
        //查询接口调用次数详情
        List<InterfaceInfoCount> UserInterfaceList = userInterfaceInfoMapper.countInterface(limit);
        // 输出
        System.out.println(JSONUtil.toJsonStr(UserInterfaceList));
        // 过滤掉接口id为空的数据
        List<InterfaceInfoCount> NewUserInterfaceList = UserInterfaceList.stream()
            .filter(item -> item.getInterfaceId() != null)
            .collect(Collectors.toList());
        // 输出新的用户接口信息
        System.out.println(JSONUtil.toJsonStr(NewUserInterfaceList));
        //将接口信息按照接口id分组，便于关联查询
        Map<Long,List<InterfaceInfoCount>> interfaceInfoMap = NewUserInterfaceList.stream()
                .collect(Collectors.groupingBy(InterfaceInfoCount::getInterfaceId));
        System.out.println(JSONUtil.toJsonStr(interfaceInfoMap));
        //构建一个查询接口详细信息的条件包装器
        QueryWrapper<InterfaceInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id",interfaceInfoMap.keySet());
        //查询接口详细信息
        List<InterfaceInfo> interfaceInfoDetails = InterfaceInfoService.list(queryWrapper);

        //将接口调用次数和接口详细信息封装到InterfaceInfoVo对象中并返回
        List<InterfaceInfoVo> interfaceInfoVos = interfaceInfoDetails.stream()
                .map(interfaceInfo -> {
                    //创建一个新的InterfaceInfoVO对象
                    InterfaceInfoVo interfaceInfoVo = new InterfaceInfoVo();
                    //将接口详细信息复制到VO对象中
                    BeanUtils.copyProperties(interfaceInfo, interfaceInfoVo);
                    //从接口信息id对应的映射中获取接口调用次数
                    Integer countNum = interfaceInfoMap.get(interfaceInfo.getId()).get(0).getCountNum();
                    //设置接口调用次数
                    interfaceInfoVo.setCountSum(countNum);
                    return interfaceInfoVo;
                })
                // 根据countSum排序（默认升序）
                .sorted(Comparator.comparing(InterfaceInfoVo::getCountSum).reversed())
                .collect(Collectors.toList());

        // 将数据保存到本地Map集合中
        log.info("将数据保存到redis缓存中");
        redisTemplate.opsForValue().set(INTERFACE_INFO_COUNT_KEY + limit, interfaceInfoVos ,INTERFACE_INFO_COUNT_EXPIRE, TimeUnit.MILLISECONDS);
//        log.info("将数据保存到缓存中");
        return interfaceInfoVos;
    }
}
